using System;
using System.Collections.Generic;
using GameFramework.Fsm;
using GameFramework.Procedure;
using GameFramework.Resource;
using UnityEditor;
using UnityEngine;
using UnityGameFramework.Runtime;
using XLua;

public abstract class LuaBaseProcedure : GameBaseProcedure
{
    private LuaTable scriptEnv = null;
    private static Action luaEnter;
    private static Action luaUpdate;
    private static Action luaDestroy;
    private static Action luaLeave;
    protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
    {
        var luaModule = procedureOwner.GetData<VarString>("luaProcedureName");

        LoadLua(luaModule);
        // string str1 = "aaaaaaaaaaaa";
        // string str2 = "aaaaaaaaaaaa";
        // Action<object> test1 = test;
        // var t1 = new KeyValuePair<string, int>(str1, test1.GetHashCode()).GetHashCode();
        // var t2 = new KeyValuePair<string, int>(str2, test1.GetHashCode()).GetHashCode();
        // test1 = test2;
        // var t3 = new KeyValuePair<string, int>(str1, test1.GetHashCode()).GetHashCode();
        //
        //
        // Debug.Log($"equal check ================= {t1.Equals(t2)}");
        // Debug.Log($"equal check22222 ================= {t1.Equals(t3)}");
    }
    
    private void test(object a)
    {}
    
    private void test2(object b)
    {}

    // private void LoadLua(string moduleFile)
    // {
    //     scriptEnv = EntityInst.Lua.Env.NewTable();
    //
    //     Debug.Log($"----- 进入lua procedure -- {moduleFile}");
    //     var env = EntityInst.Lua.Env;
    //     
    //     env.DoString($"require '{moduleFile}'","LuaProcedure", scriptEnv);
    //     
    //     env.Global.Get("OnEnter", out luaEnter);
    //     env.Global.Get("OnUpdate", out luaUpdate);
    //     env.Global.Get("OnLeave", out luaLeave);
    //     env.Global.Get("OnDestroy", out luaDestroy);
    //     
    //     luaEnter?.Invoke();
    // }
    
    private void LoadLua(string moduleFile)
    {
        scriptEnv = EntityInst.Lua.Env.NewTable();
        // 为每个脚本设置一个独立的环境，可一定程度上防止脚本间全局变量、函数冲突
        LuaTable meta = EntityInst.Lua.Env.NewTable();
        meta.Set("__index", EntityInst.Lua.Env.Global);                 //__index，lua解释器会默认执行 当要访问的字段不存在时，会去__index域对应的值（可以是函数，也可以是表）中去匹配
        scriptEnv.SetMetaTable(meta);
        meta.Dispose();
        
        EntityInst.Lua.DoString(moduleFile,"LuaProcedure", scriptEnv);
        //EntityInst.Lua.Env.DoString( $"require '{moduleFile}'","LuaProcedure", scriptEnv);
        
        scriptEnv.Get("OnEnter", out luaEnter);
        scriptEnv.Get("OnUpdate", out luaUpdate);
        scriptEnv.Get("OnLeave", out luaLeave);
        scriptEnv.Get("OnDestroy", out luaDestroy);
        
        luaEnter?.Invoke();
    }

    protected override void OnNewUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds, float realElapseSeconds)
    {
        luaUpdate?.Invoke();
    }

    protected override void OnLeave(IFsm<IProcedureManager> procedureOwner, bool isShutdown)
    {
        base.OnLeave(procedureOwner, isShutdown);
        
        luaLeave?.Invoke();
        
        scriptEnv.Dispose();
        scriptEnv = null;
        luaEnter = null;
        luaUpdate = null;
        luaLeave = null;
    }

    protected override void OnDestroy(IFsm<IProcedureManager> procedureOwner)
    {
        base.OnDestroy(procedureOwner);
        
        luaDestroy?.Invoke();
    }
}


public sealed class LuaProcedure : LuaBaseProcedure
{
}